minGPT bpe.py

示例运行

bpe.py 直接可以运行,提供了一个示例:

原始输入文本为:Hello!! I'm Andrej Karpathy. It's 2022. w00t :D 🤗

首先文本会经过预处理(分词),得到如下结果:

['Hello', '!!', ' I', "'m", ' Andrej', ' Karpathy', '.', ' It', "'s", ' 2022', '.', ' w', '00', 't', ' :', 'D', ' �'']

之后会针对每个单词进行编码:

token token_bytes token_translated token_merged token_ix
'Hello' b'Hello' 'Hello' ['Hello'] [15496]
'!!' b'!!' '!!' ['!!'] [3228]
' I' b' I' 'ĠI' ['ĠI'] [314]
"'m" b"'m" "'m" ["'m"] [1101]
' Andrej' b' Andrej' 'ĠAndrej' ['ĠAndre', 'j'] [10948, 73]
'.' b'.' '.' ['.'] [13]
' It' b' It' 'ĠIt' ['ĠIt'] [632]
"'s" b"'s" "'s" ["'s"] [338]
' 2022' b' 2022' 'Ġ2022' ['Ġ2022'] [33160]
'.' b'.' '.' ['.'] [13]
' w' b' w' 'Ġw' ['Ġw'] [266]
'00' b'00' '00' ['00'] [405]
't' b't' 't' ['t'] [83]
' :' b' :' 'Ġ:' ['Ġ:'] [1058]
'D' b'D' 'D' ['D'] [35]
' 🤗' b' \xf0\x9f\xa4\x97' 'ĠðŁ¤Ĺ' ['ĠðŁ', '¤', 'Ĺ'] [12520, 97, 245]

最后源文本编码后的输出为:

[15496, 3228, 314, 1101, 10948, 73, 509, 5117, 10036, 13, 632, 338, 33160, 13, 266, 405, 83, 1058, 35, 12520, 97, 245]

这个结果可以传入 Transformer 了!

get_encoder

该函数用于初始化编码器。

首先需要下载 GPT-2 的 encoder.json。encoder.json 的作用是什么呢?

encoder.json 是一个包含原始映射关系的 JSON 文件,它将 token 映射到 BPE(Byte Pair Encoding)索引。在这个文件中,共有 50257 个映射关系,包括 256 个单字节 token,50,000 个合并后的 token,以及一个特殊的 <|endoftext|>

接下来下载 GPT-2 的 vocab.bpe。vocab.bpe 的作用是什么呢?

vocab.bpe 是一个包含 BPE(Byte Pair Encoding)合并操作的文件。在这个文件中,存储了一个 BPE 树结构,用于表示如何将一对字符(a, b)合并为一个新的字符 ab。在这个代码片段中,vocab.bpe 文件被下载并读取,然后将其中的合并操作转换为一个包含元组的列表 bpe_merges。

BPE 的作用是将文本分割成更小的子单元,这样可以在保留语义信息的同时减少词汇表的大小。在 NLP 任务中,这有助于提高模型的性能和泛化能力。

最终用这两份数据创建编码器:

enc = Encoder(encoder, bpe_merges)

这两个文件:

Encoder

encode_and_show_work

对传入字符串进行编码,并保存编码后的结果返回,结果用于展示目的。

首先,初始化数据结构:

# 初始化bpe_idx列表
bpe_idx = [] 

# 初始化parts列表
parts = [] 

使用正则从文本中提取出所有单词:

# 使用正则表达式从文本中提取所有单词
tokens = re.findall(self.pat, text) 

对单词进行遍历:

for token in tokens:

每个单词执行操作:

# 将单词编码为字节
token_bytes = token.encode('utf-8')

# 将所有字节转换为它们的Unicode字符串表示形式并拼接
# 其中byte_encoder保存了一个Unicode映射表
token_translated = ''.join(self.byte_encoder[b] for b in token_bytes)

# 执行所有适用的BPE合并,根据self.bpe_ranks
token_merged = self.bpe(token_translated).split(' ')

# 将所有BPE令牌转换为整数
token_ix = [self.encoder[bpe_token] for bpe_token in token_merged]

# 将所有整数扩展到bpe_idx列表中
bpe_idx.extend(token_ix) 

token_translated 的具体编码过程是:

token_merged 的具体过程是:

bpe

bpe 流程调试如下。

以 token 为 Hello 为例:

将 token 打散得到 word=('H', 'e', 'l', 'l', 'o')。

根据 word 建立 pairs=

进入循环迭代过程:


本文作者:Maeiee

本文链接:minGPT bpe.py

版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!


喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!